package controller

import (
	"github.com/gin-gonic/gin"
	"golang.org/x/crypto/bcrypt"
	"log"
	"myserver/initParam"
	"myserver/middleware"
	"myserver/model"
	"myserver/param"
	"myserver/response"
	"myserver/service"
	"myserver/tool"
)

type UserController struct {
}

var userService = service.UserService{}

func (c *UserController) Router(engine *gin.Engine) {
	engine.POST("/api/login_pwd", c.nameLogin)
	engine.POST("/api/register", c.register)
	apiGroup := engine.Group("/api", middleware.AuthMiddleware())
	//apiGroup := engine.Group("/api")
	apiGroup.GET("/captcha", c.captcha)
	apiGroup.GET("/auth/info", c.Info)

	apiGroup.POST("/user", c.nameLogin)
	apiGroup.GET("/user", c.queryUser)
	apiGroup.DELETE("/user", c.deleteUser)
	apiGroup.PUT("/user", c.updateUser)
	apiGroup.GET("/users", c.queryUsers)

	//单独测试验证码
	apiGroup.POST("/verifyCaptcha", c.verifyCaptcha)
	initParam.IniParam()
}

//用户名密码登录
func (c *UserController) nameLogin(context *gin.Context) {
	//1.解析用户登录传递参数
	var loginParam param.LoginParam
	err := tool.Decode(context.Request.Body, &loginParam)
	if err != nil {
		response.Failed(context, response.Error().AddData("msg", "参数解析失败"))
		return
	}

	//2.验证验证码
	//res := tool.VerityCaptcha(loginParam.Id, loginParam.Value)
	//if !res {
	//	response.Failed(context, "验证码不正确， 请重新验证")
	//	return
	//}
	//3.登录
	user := userService.Login(loginParam.Name, []byte(loginParam.Password))

	//4.发送token
	token, err := tool.ReleaseToken(user)
	if err != nil {
		response.Failed(context, response.Ok().AddData("msg", "token生成失败"))
		log.Println("err = ", err)
		return
	}
	if user.ID != 0 {
		response.Success(context, response.Ok().AddData("token", token).AddData("user", user))
	} else {
		response.Failed(context, response.Error().AddData("msg", "登录失败"))
	}
}

func (c *UserController) queryUser(context *gin.Context) {
	query, err := context.GetQuery("ID")
	if err == false {
		response.Failed(context, response.Ok().AddData("msg", "参数解析失败"))
		return
	}
	user := userService.QueryUser(query)
	if user.ID != 0 {
		response.Success(context, response.Ok().AddData("res", user))
	} else {
		response.Failed(context, response.Error().AddData("res", "查询失败 可能是未发现记录"))
	}
}

func (c *UserController) captcha(context *gin.Context) {
	// todo 生成验证码 并返回客户端
	tool.GenerateCaptchaHandler(context)
}

func (c *UserController) verifyCaptcha(context *gin.Context) {
	var captcha tool.CaptchaResult
	err := tool.Decode(context.Request.Body, &captcha)
	if err != nil {
		response.Failed(context, response.Ok().AddData("msg", "参数解析失败"))
		return
	}
	result := tool.VerityCaptcha(captcha.Id, captcha.VerityValue)
	if result {
		log.Println("验证通过")
	} else {
		log.Println("验证失败")
	}
}

func (c *UserController) register(context *gin.Context) {
	var user model.User
	err := tool.Decode(context.Request.Body, &user)
	if err != nil {
		log.Println("err = ", err)
		response.Failed(context, response.Ok().AddData("msg", "参数解析失败"))
		return
	}

	//加密密码
	password, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost)
	user.Password = string(password)
	res := userService.CreateUser(user)
	if res != 0 {
		response.Success(context, response.Ok())
	} else {
		response.Failed(context, response.Error())
	}
}

func (c *UserController) deleteUser(context *gin.Context) {
	var user model.User
	err := context.ShouldBind(&user)
	if err != nil {
		log.Println(err)
	}
	//id, b := context.GetQuery("ID")
	//if !b {
	//	response.Failed(context, response.Error().AddData("msg", "参数解析失败"))
	//	return
	//}
	//userId, _ := strconv.ParseUint(id, 10, 64)
	//user.ID = uint(userId)
	if user.ID == 0 {
		response.Failed(context, response.Ok().AddData("msg", "参数解析失败"))
		return
	}
	var res = userService.DeleteUser(user)
	if res != 0 {
		response.Success(context, response.Ok().AddData("msg", "删除成功"))
	} else {
		response.Failed(context, response.Error().AddData("msg", "删除失败"))
	}
}

func (c *UserController) updateUser(context *gin.Context) {
	var user model.User
	err := tool.Decode(context.Request.Body, &user)
	if err != nil {
		response.Failed(context, response.Ok().AddData("msg", "参数解析失败"))
		return
	}
	var res = userService.UpdateUser(user)
	if res != 0 {
		response.Success(context, response.Ok().AddData("msg", "修改成功"))
	} else {
		response.Failed(context, response.Ok().AddData("msg", "修改失败"))
	}
}

func (c *UserController) Info(context *gin.Context) {
	user, _ := context.Get("user")
	response.Success(context, gin.H{
		"code": 200,
		"user": param.ToUserDto(user.(model.User)),
	})
}

func (c *UserController) queryUsers(context *gin.Context) {
	var pageParam param.PageParam
	err := context.ShouldBind(&pageParam)
	if err != nil {
		response.Failed(context, response.Error().AddData("msg", "参数解析失败"))
	}
	res := userService.QueryUsers(pageParam)
	if res.Data != nil && res.Total != 0 {
		response.Success(context, response.Ok().AddData("res", res))
	} else {
		response.Failed(context, response.Ok().AddData("res", res))
	}
}
